
<template>
  <div class="upload">
    <div class="list" :class="textAlign">
      <div
        class="item"
        v-for="(item,index) in list"
        :key="index"
        :style="{
        width: width?width+'px':'100px',
        height: width?width+'px':'100px'
      }"
      >
        <img :src="item.baseUrl || item.url" alt class="previewImg" />
        <div v-if="canEdit == true" class="imgMask">
          <div>
            <el-button size="mini" circle icon="el-icon-zoom-in" @click="preview(index)"></el-button>
            <!-- <el-button size="mini" circle icon="el-icon-delete" @click="delImg(index)"></el-button> -->
          </div>
          <div v-if="list.length>1">
            <el-button size="mini" icon="el-icon-d-arrow-left" plain circle @click="prev(index)"></el-button>
            <el-button size="mini" icon="el-icon-d-arrow-right" plain circle @click="next(index)"></el-button>
          </div>
        </div>
      </div>
      <div 
        class="item"
        v-show="list.length < n || !n"
        @click="chooseImg"
        :style="{
        width: width?width+'px':'100px',
        height: width?width+'px':'100px'
      }"
      >
        <input
          type="file"
          class="fileInput"
          ref="fileInput"
          @change="fileChange($event.target.files)"
          multiple
          accept="image/*"
        />
        <i v-if="!loading" class="el-icon-plus"></i>
        <i v-else class="el-icon-loading"></i>
      </div>
    </div>
  </div>
</template>
<script>
import axios from "axios";
import { qiniuToken } from "@/api/common";
axios.defaults.headers.common["Content-Type"] =
  "application/x-www-form-urlencoded";
axios.defaults.headers.common["Accept"] = "*/*";
const axiosInstance = axios.create({ withCredentials: false });
let baseMap = {}
export default {
  data() {
    return {
      list: [],
      loading: false
    };
  },
  props: {
    //是否显示主图或者轮播图
    // isShowtext:{type: Boolean,default:() => false},
    canEdit: { type: Boolean, default: () => true},
    //集合名称
    flieName: { type: String, default: () => "" },
    //文本格式
    textAlign: { type: String, default: () => "" },
    //允许单次选择的数量
    n: { type: Number, default: () => 1 },
    //文件的宽高
    width: { type: Number, default: () => 100 },
    //默认原始数据
    oldImgs: { type: Array, default: () => [] },
    //索引用来区分循环
    index: { type: Number, default: () => -1 },
    // 上传时候额外返回的值
    item: {
      type: Object,
      default: () => {
        return {};
      }
    }
  },
  created() {
    const newValue = this.oldImgs;
    this.defaultImgs(newValue);
  },
  watch: {
    oldImgs(newValue) {
      this.defaultImgs(newValue);
    }
  },
  methods: {
    fileChange(file) {
      let num = this.list.length
      if (file) {
        for (let index = 0; index < file.length; index++) {
          num++
          if (num <= this.n) {
            this.uploadFile(file[index])
          }
        }
      }
    },
    uploadFile(file) {
      if (file.size < 1100000) {
        const fileName = file.name;
        const suffix = fileName
          .substring(fileName.lastIndexOf(".") + 1)
          .toUpperCase();
        if (
          suffix === "BMP" ||
          suffix === "JPG" ||
          suffix === "JPEG" ||
          suffix === "PNG" ||
          suffix === "GIF"
        ) {
          this.loading = true;

          qiniuToken({})
            .then(res => {
              const token = res.data.token;
              const imgUrl = res.data.bind_url || res.data.url;
              let data = new FormData();
              data.append("token", token); //七牛需要的token，叫后台给，是七牛账号密码等组成的hash
              data.append("file", file);
              axiosInstance({
                method: "POST",
                url: "https://upload.qiniup.com/", //上传地址
                data: data,
                timeout: 30000 //超时时间，因为图片上传有可能需要很久
                // onUploadProgress: (progressEvent)=> {
                //     //imgLoadPercent 是上传进度，可以用来添加进度条
                //     let imgLoadPercent = Math.round(progressEvent.loaded * 100 / progressEvent.total);
                // },
              })
                .then(async data => {
                  this.loading = false;
                  let uData = {};
                  uData.url = imgUrl + "/" + data.data.key;
                  if (process.env.NODE_ENV == "development") {
                    uData.baseUrl = await this.getImgBase64(uData.url);
                  }
                  this.list.push(uData);
                  const backData = {
                    name: this.flieName,
                    files: this.list,
                    index: isNaN(this.index) ? -1 : this.index
                  };
                  this.$emit("getFile", backData, this.item);
                  //上传成功...  (登录七牛账号，找到七牛给你的 URL地址) 和 data里面的key 拼接成图片下载地址
                })
                .catch(() => {
                  //上传失败
                  this.loading = false;
                  this.$message.error("上传失败，请重新上传！");
                });
            })
            .catch(() => {
              this.loading = false;
            });
        } else {
          this.$message.error("文件类型不正确,请重新上传！");
        }
      } else {
        this.$message.error("图片大小超过1M,请重新上传");
      }
    },
    chooseImg() {
      if (!this.loading && this.canEdit) {
        this.$refs.fileInput.click();
      }
    },
    prev(index) {
      if (index !== 0) {
        const oldArr = [...this.list];
        this.list[index - 1] = oldArr[index];
        this.list[index] = oldArr[index - 1];
        const backData = {
          name: this.flieName,
          files: this.list,
          index: isNaN(this.index) ? -1 : this.index
        };
        this.$emit("getFile", backData);
      }
    },
    next(index) {
      if (index !== this.list.length - 1) {
        const oldArr = [...this.list];
        this.list[index + 1] = oldArr[index];
        this.list[index] = oldArr[index + 1];
        const backData = {
          name: this.flieName,
          files: this.list,
          index: isNaN(this.index) ? -1 : this.index
        };
        this.$emit("getFile", backData);
      }
    },
    preview(index) {
      this.$alert(
        `<img src="${this.list[index].baseUrl ||
          this.list[index].url}" width="100%" alt="">`,
        "图片预览",
        { dangerouslyUseHTMLString: true, showConfirmButton: false }
      );
    },
    delImg(index) {
      this.list.splice(index, 1);
      this.$refs.fileInput.value = ""; //请空input
      const backData = {
        name: this.flieName,
        files: this.list,
        index: isNaN(this.index) ? -1 : this.index
      };
      this.$emit("getFile", backData);
    },
    async defaultImgs(newValue) {
      const list = [];
      if (typeof newValue === "string" && newValue !== "") {
        let uData = {};
        uData.url = newValue;
        if (process.env.NODE_ENV == "development") {
          uData.baseUrl = await this.getImgBase64(uData.url);
        }
        list.push(uData);
      } else if (newValue instanceof Array) {
        newValue.forEach(async item => {
          if (item) {
            let uData = {};
            uData.url = item;
            if (process.env.NODE_ENV == "development") {
              uData.baseUrl = await this.getImgBase64(uData.url);
            }
            list.push(uData);
          }
        });
      }
      this.list = list;
    },
    getImgBase64(url) {
      return new Promise((resolve, reject) => {
        if (baseMap[url]) {
          resolve(baseMap[url])
        } else {
          axiosInstance
            .get(
              "http://localhost:8444/getQiniuImg?url=" + encodeURIComponent(url)
            )
            .then(res => {
              baseMap[url] = "data:image/png;base64," + res.data
              resolve(baseMap[url]);
            })
            .catch(() => {
              reject(url);
            });
        }
      });
    }
  }
};
</script>
 
<style lang="scss" scoped>
.list {
  font-size: 0;
  &::after {
    content: "";
    display: block;
    clear: both;
  }
  .item {
    float: left;
    display: flex;
    justify-content: center;
    align-items: center;
    vertical-align: middle;
    font-size: 24px;
    height: 100px;
    width: 100px;
    border-radius: 6px;
    border: 1px dashed #d9d9d9;
    position: relative;
    overflow: hidden;
    margin: 0 12px 12px 0;
    line-height: 100px;
    text-align: center;
    cursor: pointer;
    .previewImg {
      height: 100%;
      width: 100%;
    }
    .el-icon-loading {
      color: #fc501c;
    }
    .imgMask {
      position: absolute;
      left: 0;
      top: 0;
      height: 100%;
      width: 100%;
      background: rgba(0, 0, 0, 0.3);
      opacity: 0;
      transition: opacity 0.5s;
      color: #fff;
      line-height: 1.5;
      display: flex;
      align-items: center;
      justify-content: center;
      flex-wrap: wrap;
    }
    &:hover {
      .imgMask {
        opacity: 1;
      }
    }
    .fileInput {
      display: none;
    }
    .el-button {
      height: auto;
    }
  }
}
.tc {
  .item {
    margin: 0 auto;
  }
}
</style>